#include "tcp_receiver.hh"

// Dummy implementation of a TCP receiver

// For Lab 2, please replace with a real implementation that passes the
// automated checks run by `make check_lab2`.

template <typename... Targs>
void DUMMY_CODE(Targs &&... /* unused */) {}

using namespace std;

void TCPReceiver::segment_received(const TCPSegment &seg) {
    const TCPHeader header=seg.header();
    if(!_syn_recved&&!header.syn)
    return;
    if(!_syn_recved&&header.syn){
        _syn_recved=true;
        _isn=header.seqno;
        if(header.fin){
            _fin_recved=true;
            eof=true;
           
        }
         _reassembler.push_substring(seg.payload().copy(),0,eof);
        return;
    }
    if(!_fin_recved&&header.fin){
        _fin_recved=true;
        eof=true;
    }
    //处理数据段部分。
    uint64_t checkpoint=_reassembler.stream_out().bytes_written();
    uint64_t absolute_seq=unwrap(header.seqno,_isn,checkpoint);
    string data=seg.payload().copy();
    uint64_t index=absolute_seq-1;
    _reassembler.push_substring(data,index,eof);
}

std::optional<WrappingInt32> TCPReceiver::ackno() const {
    if (!_syn_recved) {
        return nullopt;
    }

    uint64_t abs_seqno = stream_out().bytes_written();
    // FIN also accounts for one byte, but make sure that the reassembler
    // have successfully received the EOF signal and ended the input stream. 
    // Otherwise, something went wrong and The FIN means nothing.
    if (_fin_recved && stream_out().input_ended()) {
        abs_seqno++;
    }
    return optional<WrappingInt32>(wrap(abs_seqno + 1, _isn));
 }

size_t TCPReceiver::window_size() const { return _reassembler.stream_out().remaining_capacity(); }
